use std::rc::Rc;
use std::cell::RefCell;

pub struct TwentyFourNode {
    k: u32,
    d: RefCell<i32>,
    pi: RefCell<Option<Rc<TwentyFourNode>>>,
}

impl TwentyFourNode {
    pub fn build(k: u32) -> Rc<TwentyFourNode> {
        Rc::new(TwentyFourNode {
            k,
            d: RefCell::new(i32::MAX),
            pi: RefCell::new(None),
        })
    }
    pub fn set_d(&self, d: i32) {
        *(self.d.borrow_mut()) = d;
    }
    pub fn set_pi(&self, pi: Rc<TwentyFourNode>) {
        *(self.pi.borrow_mut()) = Some(Rc::clone(&pi));
    }
    pub fn get_d(&self) -> i32 {
        unsafe {
            *(self.d.as_ptr())
        }
    }
    pub fn get_pi(&self) -> Option<Rc<TwentyFourNode>> {
        unsafe {
            if let Some(pi) = &(*(self.pi.as_ptr())) {
                Some(Rc::clone(pi))
            } else {
                None
            }
        }
    }
    pub fn get_k(&self) -> u32 {
        self.k
    }
}

pub struct TwentyFourAdjacencyListNode {
    node: Rc<TwentyFourNode>,
    list: Vec<(Rc<TwentyFourNode>, i32)>,
}

impl TwentyFourAdjacencyListNode {
    pub fn build(node: Rc<TwentyFourNode>, list: Vec<(Rc<TwentyFourNode>, i32)>) -> TwentyFourAdjacencyListNode {
        let mut list_temp = vec![];
        for (n, w) in list.iter() {
            list_temp.push((Rc::clone(n), *w));
        }
        TwentyFourAdjacencyListNode {
            node,
            list: list_temp,
        }
    }
    pub fn get_v(&self) -> Rc<TwentyFourNode> {
        Rc::clone(&self.node)
    }
    pub fn get_list(&self) -> Vec<(Rc<TwentyFourNode>, i32)> {
        let mut res = vec![];
        for (n, w) in self.list.iter() {
            res.push((Rc::clone(n), *w));
        }
        res
    }
}

